// promise

// 定义三个常量表示状态
const PENDING = 'pending'  // 等待
const FULFILLED = 'fulfilled'   // 完成
const REJECTED = 'rejected'     // 失败

class MyPromise{
    constructor(executor){
        // executor 是一个执行器，进入会立即执行
        // 并传入resolve 和 reject 方法
        try {
            executor(this.resolve,this.reject)
        } catch (error) {
            this.reject(error) 
        }
    }

    // 储存状态的变量，初始值是 pending
    status = PENDING;

    // 成功后的值
    value = null;

    // 失败后的原因
    reason = null;

    // 存储成功回调函数
    // onFulfilledCallback = null;
    onFulfilledCallbacks = []

    // 存储失败回调函数
    // onRejectedCallback = null;
    onRejectedCallbacks = []

    // 更改成功后的状态
    resolve = (value)=>{
        // 只有状态是等待，才执行状态修改
        if(this.status === PENDING){
            // 状态修改为成功
            this.status = FULFILLED;
            // 保存成功之后的值
            this.value = value;

            // 判断成功回调是否存在，如果存在就调用
            // this.onFulfilledCallback && this.onFulfilledCallback(value)
            // resolve 里面将所有成功的回调拿出来执行
            while(this.onFulfilledCallbacks.length){
                this.onFulfilledCallbacks.shift()(value)
            }
        }
    }

    // 更改失败后的状态
    reject = (reason)=>{
        // 只有状态是等待，才执行状态修改
        if(this.status === PENDING){
            // 状态修改为失败
            this.status = REJECTED;
            // 保存失败后的原因
            this.reason - reason

            // 判断失败回调是否存在，如果存在就调用
            // this.onRejectedCallback && this.onRejectedCallback(reason)
            // resolve里面将所有失败的回调拿出来执行
            while(this.onRejectedCallbacks.length){
                this.onRejectedCallbacks.shift()(reason)
            }
        }
    }

    then(onFulfilled,onRejected){
        // 如果不传，就使用默认函数
        onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value;
        onRejected = typeof onRejected === 'function' ? onFulfilled : reason => {throw reason};

        // 为了链式调用 这里创建一个MyPromise,并在后面return出去
        const promise2 = new MyPromise((resolve,reject)=>{
            // 这里的内容在执行器中，会立即执行
            // 判断状态
            if(this.status === FULFILLED){
                /* 调用成功回调，并返回值
                onFulfilled(this.value) */
                
                // 创建一个微任务等待promise2完成初始化
                queueMicrotask(()=>{
                    try {
                        // 获取成功回调函数的执行结果
                        const x = onFulfilled(this.value)
                        // 传入 resolvePromise 集中处理
                        resolvePromise(promise2,x,resolve,reject)
                    } catch (error) {
                        reject(error)
                    }
                    
                })

            }else if(this.status === REJECTED){
                /* 调用失败回调，并返回失败原因
                onRejected(this.reason) */

                // 创建一个微任务等待promise2完成初始化
                queueMicrotask(()=>{
                    try {
                        // 获取成功回调函数的执行结果
                        const x = onRejected(this.reason)
                        // 传入 resolvePromise 集中处理
                        resolvePromise(promise2,x,resolve,reject)
                    } catch (error) {
                        reject(error)
                    }
                    
                })

            }else if(this.status === PENDING){
                // 因为不知道后面状态的变化情况，所以将成功回调和失败回调存储起来
                // 等到执行成功失败函数的时候再传递
                /* this.onFulfilledCallback = onFulfilled;
                this.onRejectedCallback = onRejected; */
                /* this.onFulfilledCallbacks.push(onFulfilled);
                this.onRejectedCallbacks.push(onRejected); */

                this.onFulfilledCallbacks.push(()=>{
                    // 创建一个微任务等待promise2完成初始化
                    queueMicrotask(()=>{
                        try {
                            // 获取成功回调函数的执行结果
                            const x = onFulfilled(this.value)
                            // 传入 resolvePromise 集中处理
                            resolvePromise(promise2,x,resolve,reject)
                        } catch (error) {
                            reject(error)
                        }
                        
                    })
                })

                this.onRejectedCallbacks.push(()=>{
                    // 创建一个微任务等待promise2完成初始化
                    queueMicrotask(()=>{
                        try {
                            // 获取成功回调函数的执行结果
                            const x = onRejected(this.reason)
                            // 传入 resolvePromise 集中处理
                            resolvePromise(promise2,x,resolve,reject)
                        } catch (error) {
                            reject(error)
                        }
                    })
                })
            }
        })

        return promise2; 
    }

    // resolve 静态方法
    static resolve(parameter){
        // 如果传入MyPromise 就直接返回
        if(parameter instanceof MyPromise){
            return parameter
        }

        // 转成常规方式
        return new MyPromise(resolve =>{
            resolve(parameter)
        })
    }

    // reject 静态方法
    static reject(reason){
        return new MyPromise((resolve,reject)=>{
            reject(reason)
        })
    }

}

function resolvePromise(promise2,x,resolve,reject){
    // 如果相等，说明return的是自己，抛出类型错误并返回
    if(promise2 === x){
        return reject(new TypeError('Chaining cycle detected for promise #<Promise>'))
    }
    // 判断x是不是 MyPromise 实例对象
    if(x instanceof MyPromise){
        // 执行x, 调用then方法，目的是将其状态变为 fulfilled 或 rejected
        x.then(resolve,reject)
    }else{
        resolve(x)
    }
}

module.exports = MyPromise;